package sync_bank_test;

import java.util.concurrent.locks.*;

public class Bank {
    private final double[] accounts;
    private Lock bankLock;
    private Condition sufficientFunds;
    public Bank(int n, double initialBalance) {
	accounts = new double[n];
	for (int i = 0; i < accounts.length; i++)
	    accounts[i] = initialBalance;
	bankLock = new ReentrantLock();
	sufficientFunds = bankLock.newCondition();
    }

    public void transfer(int from, int to, double amount) throws InterruptedException {
	bankLock.lock();
	try {
	    while (accounts[from] < amount) {
		sufficientFunds.await();
//		System.err.println("waiting!");
	    }
	    System.out.print(Thread.currentThread());
	    accounts[from] -= amount;
	    System.out.printf(" %10.2f from %d to %d\n", amount, from, to);
	    System.out.printf(" acount %d has %10.2f left, account %d now has %10.2f\n", from, accounts[from], to, accounts[to]);
	    accounts[to] += amount;
	    System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
	    /**
	     * Good Question.
	     * Don't forget to call notifyAll()!!!!!!!!!!!
	     * Shit!! I mean, signalAll()!!!!!!!!!!
	     */
//	    sufficientFunds.notifyAll();
	    sufficientFunds.signalAll();
	}
	finally {
	    bankLock.unlock();
	}
    }

    public double getTotalBalance() {
	bankLock.lock();
	try {
	    double sum = 0;
	    for (double a : accounts)
		sum += a;

	    return sum;
	}
	finally {
	    bankLock.unlock();
	}
    }

    public int size() {
	return accounts.length;
    }
}